class cwaveform {
  // ========== contructor ========== //
  cwaveform(int rawData[], int patternLen) {
    this.rawData = rawData;
    LEN_RAWDATA = rawData.length;
    this.LEN_BAR = patternLen * width / rawData.length;

    layerBar = createGraphics(width, UPPER_WINDOW_HEIGHT);
    layerBar.beginDraw();
    layerBar.colorMode(HSB, 360, 100, 100);
    layerBar.fill(#13A3BF, 60);
    layerBar.noStroke();
    layerBar.endDraw();

    visualize();
  }

  // ========== show ========== //
  void show() {
    image(layerWaveForm, 0, 0);

    layerBar.beginDraw();
    layerBar.clear();
    layerBar.rect(mouseX, 0, LEN_BAR, UPPER_WINDOW_HEIGHT);
    layerBar.endDraw();

    image(layerBar, 0, 0);
  }

  // ========== visualize ========== //
  private void visualize() {
    layerWaveForm = createGraphics(width, UPPER_WINDOW_HEIGHT);
    layerWaveForm.beginDraw();
    layerWaveForm.colorMode(HSB, 360, 100, 100);

    final int MIN = min(rawData);
    final int MAX = max(rawData);
    int preXpos = 0;
    int preYpos = 0;

    for (int i = 0; i < LEN_RAWDATA; i++) {
      int xpos = (int)map(i, 0, LEN_RAWDATA, 0, width);
      int ypos = (int)map(rawData[i], MIN, MAX, UPPER_WINDOW_HEIGHT, 0);
      layerWaveForm.line(preXpos, preYpos, xpos, ypos);
      preXpos = xpos;
      preYpos = ypos;
    }

    layerWaveForm.endDraw();
  }

  // ========== member var ========== //
  private final int rawData[];
  private final int LEN_RAWDATA;
  private final int LEN_BAR;
  private PGraphics layerWaveForm;
  private PGraphics layerBar;
};
